<template>
  <div class="setting-container">
    <div class="app-container">
      <!-- 卡片组件 -->
      <el-card class="box-card">
        <!-- 使用 Tabs 组件完成标签页布局 -->
        <el-tabs v-model="activeName">
          <el-tab-pane label="角色管理" name="first" class="tab-pane">
            <!-- 新增角色按钮 -->
           <el-row style="height:60px">
             <el-button
               icon="el-icon-plus"
               size="small"
               type="primary"
              @click="addRoleBtnFn"
              >新增角色</el-button>
            </el-row>
            <!-- 使用 Table 组件实现用户角色的渲染 -->
            <el-table :data="rolesList" border style="width: 100%">
              <el-table-column type="index" label="序号" width="120" />
              <el-table-column prop="name" label="角色名" width="240" />
              <el-table-column prop="description" label="描述" />
              <el-table-column label="操作">
                <!--
                    vue2.6之前作用域插槽写法: slot-scope="scope"(vue向下兼容,以前的可以使用)
                    vue2.6新写法 v-slot="scope变量名" v-slot:default="scope"
                    作用域插槽scope变量值来自哪里呢?table-column里slot占位标签身上的属性
                    内部 <slot row="行数据对象" />
                    scope变量值: { row: 行数据对象 }
                    也可以写成 v-slot="scope" 或者 v-slot="{ row }"
                    要接收的是 row / data 要看文档才知道 <template #default="{row / data}" />
                 -->
                <template slot-scope="scope">
                  <el-button size="small" type="success" @click="setRoles(scope.row)">给角色分配权限点</el-button>
                  <el-button size="small" type="primary" @click="editRoles(scope.row)">编辑</el-button>
                  <el-button size="small" type="danger" @click="delRoles(scope.row)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>

            <!-- 分页区域 -->
            <el-pagination
              :current-page.sync="query.page"
              :page-sizes="[1,5,10]"
              :page-size.sync="query.pagesize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="total"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
            />
          </el-tab-pane>
          <el-tab-pane label="公司信息" class="tab-pane">
            <el-alert
              title="对公司名称、公司地址、营业执照、公司地区的更新，将使得公司资料被重新审核，请谨慎修改"
              type="info"
              show-icon
              :closable="false"
            />
            <el-form :model="companyInfo" label-width="70px" class="companyForm">
              <el-form-item label="公司名称"  >
                <el-input v-model="companyInfo.name"  disabled  class="el-form-item-ipt"/>
              </el-form-item>
              <el-form-item label="公司地址">
                <el-input v-model="companyInfo.companyAddress" disabled  class="el-form-item-ipt"/>
              </el-form-item>
              <el-form-item label="邮箱">
                <el-input v-model="companyInfo.mailbox"  disabled  class="el-form-item-ipt"/>
              </el-form-item>
              <el-form-item label="备注">
                <el-input v-model="companyInfo.remarks"  type="textarea" :rows="3" disabled  class="el-form-item-ipt"/>
              </el-form-item>
            </el-form>
          </el-tab-pane>
        </el-tabs>
      </el-card>
      <!-- 新增弹框 @update="showDialog = $event"-->
      <settingDialog :showDialog.sync="showDialog" @addRole="addRoleFn" :isEdit="isEdit"/>
      <!-- 给角色分配权限点弹框 -->
        <el-dialog title="分配权限点" :visible.sync="dialogVisible" @closed="closeFn">
          <AsignRoleTreeDialog
          ref="myDialog"
          v-model="dialogVisible"
          :permissionList="permissionList"
          :permIds="permIds"
          @saveRolePer="saveRolePer"
          />
        </el-dialog>
    </div>
  </div>
</template>

<script>
import { getRoleListAPI, getCompanyInfoAPI, addRoleAPI, getRoleDetailAPI,
getUserProfileAPI, updateRoleDetailAPI, deleteRoleDetailAPI, getPermissionListAPI,
assignPremAPI
 } from '@/api'
import settingDialog from './components/settingDialog.vue'
import AsignRoleTreeDialog from './components/asignRoleTreeDialog.vue'
import { transTree } from '@/utils/handleTreeData'
export default {
  name: 'SettingIndex',
  data() {
    return {
      activeName: 'first',
      query: {
        page: 1, // 请求第 ? 页
        pagesize: 10 // 页面显示的条数
      },
      rolesList: [], // 角色列表
      permissionList: [], // 权限点列表
      permIds: [], // 该角色已有的权限点
      currentSelectdRoldId: '', // 当前选中的角色分配权限点角色的id(保存时使用)
      total: 0, // 角色数据总条数
      companyInfo: {}, // 公司信息
      showDialog: false, // 控制新增角色弹框的隐藏和展示
      dialogVisible: false, // 控制分配角色权限点弹框的隐藏和显示
      isEdit: false, // true为修改模式/false为新增模式,通过布尔值判断是添加还是修改
    }
  },
  created(){
    this.getRoleListFn() // 获取所有角色列表
    this.getCompanyInfoFn() // 获取公司信息
    this.getPermissionListFn() // 获取权限点列表
  },
  methods: {
    // 获取所有角色列表
    async getRoleListFn(){
      const res = await getRoleListAPI(this.query)
      this.rolesList = res.data.rows
      this.total = res.data.total
    },
    // 获取公司信息
    async getCompanyInfoFn(){
      // 再次获取用户个人信息,
      /*
          问题: 进入获取公司信息页面后,刷新网页,因为vuex内的数据会被重置,
                而我们获取公司信息需要用到个人信息内的数据字段 compangId,
                而获取个人信息接口是在路由守卫里的, 先 next() 在执行发起请求(时机不对)
                因为next放行后,进入到该页面,执行到获取信息接口时,个人信息接口还未被开始执行
                所以在本页面需要额外再发送一个获取个人信息请求
      */
      const { data: { companyId } } = await getUserProfileAPI()
      const res = await getCompanyInfoAPI(companyId)
      this.companyInfo = res.data
    },
    // 获取权限点列表
    async getPermissionListFn(){
      const res = await getPermissionListAPI()
      this.permissionList = transTree(res.data,'0')
    },
     // 新增角色->按钮点击事件
    addRoleBtnFn() {
      this.isEdit = false
      this.showDialog = true
    },
    // 自定义事件,新增/编辑角色事件
    async addRoleFn(formobj){
      if(this.isEdit){ // 修改
        const res = await updateRoleDetailAPI(formobj)
        this.$message('修改成功')
      }else{ // 新增
        const res = await addRoleAPI(formobj)
        this.$message('新增角色成功')
      }
      this.getRoleListFn() // 刷新列表
    },
    // 每页显示的条数发生改变时触发
    handleSizeChange(size) {
      this.query.page = 1 // 改变展示的条目数后需要重新回到第一页开始查看,防止用户在非第一页时,切换展示条目,请求到非第一页的数据
      // 使用了.sync修饰符把条数数据同步到了 query.size 里
      this.getRoleListFn()
    },

    // 当前页面发生改变时触发
    handleCurrentChange(page) {
      // 使用了.sync修饰符把条数数据同步到了 query.page 里
      this.getRoleListFn()
    },

    // 设置角色的权限点事件
    async setRoles(rowObj) {
      this.dialogVisible = true
      this.currentSelectdRoldId = rowObj.id // 保存当前分配权限点角色的id(保存角色权限点的时候使用)
      const res = await getRoleDetailAPI(rowObj.id) // 根据id查询该角色已有的权限点
      console.log(res)
      this.permIds = res.data.permIds // 存储当前角色的已选择了的权限点
    },
    // 保存角色权限点事件
    async saveRolePer(permissionList){
      const res = await assignPremAPI({
        id: this.currentSelectdRoldId,
        permIds: permissionList
      })
      this.getPermissionListFn() // 获取权限点列表
      this.$message('为当前角色分配权限点成功')
    },
    // 编辑角色(回填信息)
    async editRoles(row) {
      this.isEdit = true
      const res = await getRoleDetailAPI(row.id) // 根据id查询相关信息进行回填
      // 原本数据只有2对 k&v 后台返回的是5对 k&v ,无所谓,可以多不可以少就行了,反正只渲染2对数据,多的不用
      this.showDialog = true // 打开 dialog
      // 延迟赋值,因为el-form还没渲染完成,就给form表单对象赋值的话,form表单对象会把回显的数据默认为第一次的初始数据,以后reset方法会有问题
      setTimeout(() => {
        this.$children[1].roleForm = res.data // 为子组件 form 表单赋值(数据驱动视图)
      },0)
    },

    // 删除角色
    /*
      bug: 最后一页,最后一条数据,会出现问题
      问题: 导致 Pagination 标签页码往前走1,但是数据没有获取到前一页的数据(因为还是请求当前页没有数据的page)
      原因: 删除最后一条,但是调用刷新列表的query.page还是之前的页码数(后台没有这也的数据返回空数组,导致表格里暂无数据)
      解决: 删除后,判断数组里剩余的个数, < 1? 对query.page参数进行修改 this.page--
    */
    async delRoles(row) {
      await deleteRoleDetailAPI(row.id)
      this.$message('删除成功')
      // rolesList数组只会保存当前页的数据,所以当它的数组长度为 < 1时就代表它是这一页的最后一条数据,删除后请求上一页数据即可
      if(this.rolesList.length <= 1){
        this.query.page--
        // 如果删到第一页最后一条数据后,数据库没有任何数据了,让请求的page为1即可,0后台不会接收并限制
        // 假设: 后台要求传递的page最小只能是1
        // 解决: 判断进入后,强制改回1
        if(this.query.page < 1){
          this.query.page = 1
        }
      }
      this.getRoleListFn()
    },
    // 关闭 dialog 弹窗事件
    closeFn(){
      this.permIds = []
    }
  },
  components: {
    settingDialog,
    AsignRoleTreeDialog
  }
}
</script>

<style lang="scss" scoped>
.companyForm {
  margin-top: 50px;
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
}
.el-form-item-ipt {
  width: 300px;
}
.box-card {
  padding: 10px 30px;
}

.tab-pane {
  padding: 20px;
}

.el-pagination {
  text-align: center;
  margin-top: 20px;
}
</style>
